const { executeInEditMode, ccclass, property } = cc._decorator;
@ccclass
@executeInEditMode
export default class Gif extends cc.Component {
    @property({
        serializable: true
    })
    _asset: cc.Asset = null;
    @property(cc.Asset)
    get asset() {
        return this._asset;
    }
    set asset(val) {
        if (this._asset === val) {
            return;
        }
        this._asset = val;
        this.refresh();
    }

    _face: cc.Sprite = null;
    @property(cc.Sprite)
    get face() {
        if (!this._face) {
            this._face = this.node.getComponent(cc.Sprite) || this.node.addComponent(cc.Sprite);
        }
        return this._face;
    }
    @property
    interval = 0.1;
    cd = 0;

    frameList: cc.SpriteFrame[] = [];
    frameInd = 0;
    protected _inited = false;
    get inited() {
        return this._inited;
    }

    protected start(): void {
        this.refresh();
    }
    async refresh() {
        this._inited = false;
        this.frameList = [];
        if (!this.assetIsGif(this._asset)) {
            return;
        }
        let gif = new Image();
        gif.src = this._asset.nativeUrl;
        await new Promise<Event>(ok => gif.onload = ok);
        let superGif = new SuperGif({ gif: gif });
        await superGif.load();
        for (let i = 0; i <= superGif.getLength(); i++) {
            superGif.moveTo(i);
            let tex = new cc.Texture2D();
            tex.initWithElement(superGif.getCanvas());
            this.frameList.push(new cc.SpriteFrame(tex));
        }
        superGif.destroy();
        superGif = null;
        this._inited = true;

        this._setFrame(0);
    }
    assetIsGif(asset: cc.Asset) {
        if (!cc.isValid(asset)) {
            return false;
        }
        return /gif/g.test(this._asset.nativeUrl.substring(this._asset.nativeUrl.lastIndexOf(".")));
    }
    protected _setFrame(ind: number) {
        this.face.spriteFrame = this.frameList[ind];
    }
    protected lateUpdate(dt: number): void {
        if (!this._inited) {
            return;
        }
        if (!CC_EDITOR) {
            this.cd += dt;
            if (this.cd > this.interval) {
                this.cd = 0;
                this.frameInd++;
                if (this.frameInd >= this.frameList.length) {
                    this.frameInd = 0;
                }
                this._setFrame(this.frameInd);
            }
        }
    }
};